package net.pluce.nxt.network.impl;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import lejos.pc.comm.NXTComm;

import net.pluce.nxt.network.EventWatcher;
import net.pluce.nxt.network.RobotConnection;
import net.pluce.nxt.network.RobotConnectionException;
import net.pluce.nxt.network.RobotListener;

/**
 * Abstract superclass for robot connection implementation. Manage listeners and launch the EventWatcher thread.
 * Every RobotConnection implementation should extend this class or launch the thread by itself.
 * @author Pluce
 */
public abstract class AbstractRobotConnection implements RobotConnection {

	protected Set<RobotListener> listeners = new HashSet<RobotListener>();
	protected NXTComm connection;
	protected EventWatcher eventWatcher;
	
	public AbstractRobotConnection() {
		super();
	}
	
	public void setEventWatcher(EventWatcher eventWatcher){
		this.eventWatcher = eventWatcher; 
	}
	
	@Override
	public boolean open() throws RobotConnectionException{
		boolean init = this.initiate();
		if(!init) return false;
		if(eventWatcher == null) throw new RobotConnectionException("Event Watcher has not been set");
		eventWatcher.setRobotConnection(this);
		(new Thread(eventWatcher)).start();
		return true;
	}

	protected abstract boolean initiate() throws RobotConnectionException;
	
	@Override
	public void addListener(RobotListener listener) {
		listeners.add(listener);
	}
	
	@Override
	public synchronized Collection<RobotListener> getListeners() {
		return listeners;
	}

	@Override
	public OutputStream getOutputStream() throws IllegalStateException{
		if(!isOpened()) throw new IllegalStateException("Connection closed");
		return connection.getOutputStream();
	}

	@Override
	public InputStream getInputStream() throws IllegalStateException{
		if(!isOpened()) throw new IllegalStateException("Connection closed");
		return connection.getInputStream();
	}

}